package com.example.finalassignment.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import com.example.finalassignment.common.Cache;
import com.example.finalassignment.common.ThreadContext;
import com.example.finalassignment.exception.ServiceException;
import com.example.finalassignment.mapper.UserInfoMapper;
import com.example.finalassignment.mapper.UserMapper;
import com.example.finalassignment.pojo.User;
import com.example.finalassignment.pojo.UserInfo;
import com.example.finalassignment.pojo.dto.UserLoginDto;
import com.example.finalassignment.pojo.dto.UserRegisterDto;
import com.example.finalassignment.pojo.dto.UserUpdateDto;
import com.example.finalassignment.pojo.response.LoginResponse;
import com.example.finalassignment.pojo.response.ResultDataResponse;
import com.example.finalassignment.pojo.response.ResultResponse;
import com.example.finalassignment.pojo.vo.UserVo;
import com.example.finalassignment.service.UserService;
import com.example.finalassignment.util.GenerateUtil;
import com.example.finalassignment.util.JwtUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    private final UserInfoMapper userInfoMapper;

    public UserServiceImpl(UserMapper userMapper, UserInfoMapper userInfoMapper) {
        this.userMapper = userMapper;
        this.userInfoMapper = userInfoMapper;
    }

    @Override
    public ResultResponse loginByToken() {
        String id = JwtUtil.getIdByToken(ThreadContext.getToken());
        Map<String, Object> stringObjectMap = userMapper.selectByIdToUserAndUserInfo(id);

        if (stringObjectMap == null) {
            throw new ServiceException(201, "用户不存在");
        }

//        System.out.println(stringObjectMap);
        return new ResultDataResponse<>(stringObjectMap);
    }

    @Override
    public ResultResponse login(UserLoginDto userLoginDto) {
//        System.out.println(userLoginDto);
        if ("".equals(userLoginDto.getUsername()) ||
                "".equals(userLoginDto.getPassword()) ||
                "null".equals(userLoginDto.getUsername()) ||
                "null".equals(userLoginDto.getPassword()) ||
                null == userLoginDto ||
                null == userLoginDto.getPassword() ||
                null == userLoginDto.getUsername()) {
            return new ResultResponse(200, "账号或密码为空", Boolean.FALSE);
        }


        User oldUser = userMapper.selectByUserNameAndPassword(userLoginDto.getUsername(), DigestUtil.md5Hex(userLoginDto.getPassword()));

        if (oldUser == null) {
            return new ResultResponse(200, "账号或密码错误", Boolean.FALSE);
        }

        String token = JwtUtil.createToken(oldUser.getId(), oldUser.getUsername());

        UserInfo userInfo = userInfoMapper.selectByUserId(oldUser.getId());

        LoginResponse loginResponse = new LoginResponse(token, 200,
                "登录成功",
                Boolean.TRUE);
        Cache.USER_INFO.put(token, JSONUtil.toJsonStr(userInfo));
//        System.out.println(Cache.USER_INFO);
        return loginResponse;
    }

    /**
     * 注册
     */
    @Override
    public ResultResponse register(UserRegisterDto userRegisterDto) {
        String username = userRegisterDto.getUsername();
        String password = userRegisterDto.getPassword();
        String confirmPassword = userRegisterDto.getConfirmPassword();
        String mailbox = userRegisterDto.getMailbox();
        String name = userRegisterDto.getName();

        // 判断是否为null
        if (username == null || password == null || confirmPassword == null || mailbox == null || name == null) {
            throw new ServiceException(201, "输入的数据有空,请检查");
        }

        // 判断是否为空
        if (username.isEmpty() || password.isEmpty() || confirmPassword.isEmpty() || mailbox.isEmpty() || name.isEmpty()) {
            throw new ServiceException(201, "输入的数据有空,请检查");
        }

        // 2次输入的密码对不对
        if (!password.equals(confirmPassword)) {
            throw new ServiceException(201, "2次输入的密码不相同,请检查");
        }

        User oldUser1 = userMapper.selectByUserNameAndPassword(username, GenerateUtil.StringByMd5(password));
        if (oldUser1 != null) {
            throw new ServiceException(201, "该账号已存在");
        }

        UserInfo oldUserInfo = userInfoMapper.selectByMailbox(name);
        if (oldUserInfo != null) {
            throw new ServiceException(201, "邮箱已存在");
        }

        String newId = GenerateUtil.generateUUID();

        User newUser = new User();
        newUser.setId(newId);
        newUser.setCreateTime(new Date());
        newUser.setUsername(username);
        newUser.setName(name);
        newUser.setPassword(GenerateUtil.StringByMd5(password));

        CompletableFuture<Integer> userCompletableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
                return userMapper.insertSelective(newUser);
            }
        });

        UserInfo newUserInfo = new UserInfo();
        newUserInfo.setUserId(newId);
        newUserInfo.setMailbox(mailbox);

        //获取头像
        List<String> pictureCache = Cache.PICTURE_CACHE;
        int idx = GenerateUtil.RANDOM.nextInt(0, pictureCache.size());
        newUserInfo.setPicture(pictureCache.get(idx));


        CompletableFuture<Integer> objectCompletableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
                return userInfoMapper.insertSelective(newUserInfo);
            }
        });

        int res = userCompletableFuture.join() + objectCompletableFuture.join();

        if(res < 2){
            throw new ServiceException(201);
        }

        return ResultResponse.success("注册成功");
    }

    /**
     * 修改用户信息
     */
    @Override
    public ResultResponse updateByUserInfo(UserUpdateDto userUpdateDto) {
        String id = JwtUtil.getIdByToken(ThreadContext.getToken());
        String picture = userUpdateDto.getPicture();

        int idx = picture.lastIndexOf('/');
        picture = picture.substring(idx + 1);

        User user = new User();
        user.setId(id);
        user.setName(userUpdateDto.getName());

        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(id);
        userInfo.setPicture(picture);
        userInfo.setAge(userUpdateDto.getAge());
        try {
            userMapper.updateByPrimaryKeySelective(user);
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
            return ResultResponse.success("修改成功");
        }catch (Exception e){
            throw new ServiceException(201,"操作失败");
        }
    }
}
